import
  \z85
  \idb : {openDB}

var DB

open = ~>
  if not DB
    DB := await openDB(
      \cache
      1
      * upgrade: (db)!~>
          for i in <[
            hash
            url
            li
          ]>
            db.createObjectStore(i, { keyPath: \k })
    )
  return DB

opened = (func) ~>
  ~>
    await open!
    func.apply(DB, arguments)


rm = (dict)!~>
  tx = DB.transaction(Object.keys(dict), \readwrite)
  for k,v of dict
    tx.objectStore(k).delete(\k , v)
  return tx.done


put = (dict)!~>
  tx = DB.transaction(Object.keys(dict), \readwrite)
  for k,v of dict
    tx.objectStore(k).put {
      k:v.shift!
      v:if v.length == 1 then v[0] else v
    }
  return tx.done


set = (url, hash, txt)~>
  old-hash = await DB.get \url, url
  if old-hash
    await rm {
      hash: old-hash
    }
  await put {
    url : [url, hash]
    hash : [hash, txt]
  }

equal = (a,b)~>
  if a.length != b.length
    return false
  for i,pos in a
    if b[pos] != i
      return false
  true

export
  by-url = opened (url)->
    $f url

  by-hash = opened (url, hash)->
    # hash = await @get \url, url
    hash = z85.decode hash
    txt = await @get \hash, hash
    if txt
      v = txt.v
    else
      v = await $get url, \arrayBuffer
      await set(
        url
        await crypto.subtle.digest(\SHA-256, v)
        new TextDecoder(\utf-8).decode v
      )
    v

    # if hash
    #   r = await @get \hash, hash.v
    #   if r
    #     return r.v
    # v = await $f url, \arrayBuffer
    # hash = await crypto.subtle.digest(\SHA-256, v)
    # txt = new TextDecoder(\utf-8).decode v
    # v = await save url, hash, txt
    # return txt

  # li-get = opened (url, hash)->
  #   r = (await @get(\li, hash))
  #   if r
  #     v = r.v
  #   else
  #     v = await save url, hash, await $f url
  #   return v

